home *** CD-ROM | disk | FTP | other *** search
/ Internet Info 1994 March / Internet Info CD-ROM (Walnut Creek) (March 1994).iso / networking / ip / ka9q / src890906.arc / TCPIN.C < prev    next >
C/C++ Source or Header  |  1989-08-19  |  23KB  |  842 lines

  1. /* Process incoming TCP segments. Page number references are to ARPA RFC-793,
  2.  * the TCP specification.
  3.  */
  4. #include "global.h"
  5. #include "timer.h"
  6. #include "mbuf.h"
  7. #include "netuser.h"
  8. #include "internet.h"
  9. #include "tcp.h"
  10. #include "icmp.h"
  11. #include "iface.h"
  12. #include "ip.h"
  13.  
  14. static void update __ARGS((struct tcb *tcb,struct tcp *seg));
  15. static void proc_syn __ARGS((struct tcb *tcb,char tos,struct tcp *seg));
  16. static void add_reseq __ARGS((struct tcb *tcb,char tos,struct tcp *seg,
  17.     struct mbuf *bp,int16 length));
  18. static void get_reseq __ARGS((struct tcb *tcb,char *tos,struct tcp *seq,
  19.     struct mbuf **bp,int16 *length));
  20. static int trim __ARGS((struct tcb *tcb,struct tcp *seg,struct mbuf **bpp,
  21.     int16 *length));
  22. static int in_window __ARGS((struct tcb *tcb,int32 seq));
  23.  
  24. struct tcp_stat Tcp_stat;
  25.  
  26. /* This function is called from IP with the IP header in machine byte order,
  27.  * along with a mbuf chain pointing to the TCP header.
  28.  */
  29. void
  30. tcp_input(bp,ip,rxbroadcast)
  31. struct mbuf *bp;    /* Data field, if any */
  32. struct ip *ip;        /* IP header */
  33. int rxbroadcast;    /* Incoming broadcast - discard if true */
  34. {
  35.     register struct tcb *tcb;    /* TCP Protocol control block */
  36.     struct tcp seg;            /* Local copy of segment header */
  37.     struct connection conn;        /* Local copy of addresses */
  38.     struct pseudo_header ph;    /* Pseudo-header for checksumming */
  39.     int hdrlen;            /* Length of TCP header */
  40.     int16 length;
  41.  
  42.     if(bp == NULLBUF)
  43.         return;
  44.  
  45.     if(rxbroadcast){
  46.         /* Any TCP packet arriving as a broadcast is
  47.          * to be completely IGNORED!!
  48.          */
  49.         Tcp_stat.bdcsts++;
  50.         free_p(bp);
  51.         return;
  52.     }
  53.     length = ip->length - IPLEN - ip->optlen;
  54.     ph.source = ip->source;
  55.     ph.dest = ip->dest;
  56.     ph.protocol = ip->protocol;
  57.     ph.length = length;
  58.     if(cksum(&ph,bp,length) != 0){
  59.         /* Checksum failed, ignore segment completely */
  60.         Tcp_stat.checksum++;
  61.         free_p(bp);
  62.         return;
  63.     }
  64.     /* Form local copy of TCP header in host byte order */
  65.     if((hdrlen = ntohtcp(&seg,&bp)) < 0){
  66.         /* TCP header is too small */
  67.         Tcp_stat.runt++;
  68.         free_p(bp);
  69.         return;
  70.     }
  71.     length -= hdrlen;
  72.  
  73.     /* Fill in connection structure and find TCB */
  74.     conn.local.address = ip->dest;
  75.     conn.local.port = seg.dest;
  76.     conn.remote.address = ip->source;
  77.     conn.remote.port = seg.source;
  78.     
  79.     if((tcb = lookup_tcb(&conn)) == NULLTCB){
  80.         struct tcb *ntcb;
  81.  
  82.         /* Check that this segment carries a SYN, and that
  83.          * there's a LISTEN on this socket with
  84.          * unspecified source address and port
  85.          */
  86.         conn.remote.address = 0;
  87.         conn.remote.port = 0;
  88.         if(!seg.flags.syn || (tcb = lookup_tcb(&conn)) == NULLTCB){
  89.             /* No unspecified LISTEN either, so reject */
  90.             free_p(bp);
  91.             reset(ip,&seg);
  92.             return;
  93.         }
  94.         /* We've found an server listen socket, so clone the TCB */
  95.         if(tcb->flags.clone){
  96.             if((ntcb = (struct tcb *)malloc(sizeof (struct tcb))) == NULLTCB){
  97.                 free_p(bp);
  98.                 /* This may fail, but we should at least try */
  99.                 reset(ip,&seg);
  100.                 return;
  101.             }
  102.             ASSIGN(*ntcb,*tcb);
  103.             tcb = ntcb;
  104.             tcb->timer.arg = tcb;
  105.         } else
  106.             unlink_tcb(tcb);    /* It'll be put back on later */
  107.  
  108.         /* Stuff the foreign socket into the TCB */
  109.         tcb->conn.remote.address = ip->source;
  110.         tcb->conn.remote.port = seg.source;
  111.  
  112.         /* NOW put on right hash chain */
  113.         link_tcb(tcb);
  114.     }
  115.     /* Do unsynchronized-state processing (p. 65-68) */
  116.     switch(tcb->state){
  117.     case CLOSED:
  118.         free_p(bp);
  119.         reset(ip,&seg);
  120.         return;
  121.     case LISTEN:
  122.         if(seg.flags.rst){
  123.             free_p(bp);
  124.             return;
  125.         }
  126.         if(seg.flags.ack){
  127.             free_p(bp);
  128.             reset(ip,&seg);
  129.             return;
  130.         }
  131.         if(seg.flags.syn){
  132.             /* (Security check is bypassed) */
  133.             /* page 66 */
  134.             Tcp_stat.conin++;
  135.             proc_syn(tcb,ip->tos,&seg);
  136.             send_syn(tcb);
  137.             setstate(tcb,SYN_RECEIVED);        
  138.             if(length != 0 || seg.flags.fin) {
  139.                 /* Continue processing if there's more */
  140.                 break;
  141.             }
  142.             tcp_output(tcb);
  143.         }
  144.         free_p(bp);    /* Unlikely to get here directly */
  145.         return;
  146.     case SYN_SENT:
  147.         if(seg.flags.ack){
  148.             if(!seq_within(seg.ack,tcb->iss+1,tcb->snd.nxt)){
  149.                 free_p(bp);
  150.                 reset(ip,&seg);
  151.                 return;
  152.             }
  153.         }
  154.         if(seg.flags.rst){    /* p 67 */
  155.             if(seg.flags.ack){
  156.                 /* The ack must be acceptable since we just checked it.
  157.                  * This is how the remote side refuses connect requests.
  158.                  */
  159.                 close_self(tcb,RESET);
  160.             }
  161.             free_p(bp);
  162.             return;
  163.         }
  164.         /* (Security check skipped here) */
  165.         /* Check incoming precedence; it must match if there's an ACK */
  166.         if(seg.flags.ack && PREC(ip->tos) != PREC(tcb->tos)){
  167.             free_p(bp);
  168.             reset(ip,&seg);
  169.             return;
  170.         }
  171.         if(seg.flags.syn){
  172.             proc_syn(tcb,ip->tos,&seg);
  173.             if(seg.flags.ack){
  174.                 /* Our SYN has been acked, otherwise the ACK
  175.                  * wouldn't have been valid.
  176.                  */
  177.                 update(tcb,&seg);
  178.                 setstate(tcb,ESTABLISHED);
  179.             } else {
  180.                 setstate(tcb,SYN_RECEIVED);
  181.             }
  182.             if(length != 0 || seg.flags.fin) {
  183.                 break;        /* Continue processing if there's more */
  184.             }
  185.             tcp_output(tcb);
  186.         } else {
  187.             free_p(bp);    /* Ignore if neither SYN or RST is set */
  188.         }
  189.         return;
  190.     }
  191.     /* We reach this point directly in any synchronized state. Note that
  192.      * if we fell through from LISTEN or SYN_SENT processing because of a
  193.      * data-bearing SYN, window trimming and sequence testing "cannot fail".
  194.      */
  195.  
  196.     /* Trim segment to fit receive window. */
  197.     if(trim(tcb,&seg,&bp,&length) == -1){
  198.         /* Segment is unacceptable */
  199.         if(!seg.flags.rst){    /* NEVER answer RSTs */
  200.             /* In SYN_RECEIVED state, answer a retransmitted SYN 
  201.              * with a retransmitted SYN/ACK.
  202.              */
  203.             if(tcb->state == SYN_RECEIVED)
  204.                 tcb->snd.ptr = tcb->snd.una;
  205.             tcb->flags.force = 1;
  206.             tcp_output(tcb);
  207.         }
  208.         return;
  209.     }
  210.     /* If segment isn't the next one expected, and there's data
  211.      * or flags associated with it, put it on the resequencing
  212.      * queue, ACK it and return.
  213.      *
  214.      * Processing the ACK in an out-of-sequence segment without
  215.      * flags or data should be safe, however.
  216.      */
  217.     if(seg.seq != tcb->rcv.nxt
  218.      && (length != 0 || seg.flags.syn || seg.flags.fin)){
  219.         add_reseq(tcb,ip->tos,&seg,bp,length);
  220.         tcb->flags.force = 1;
  221.         tcp_output(tcb);
  222.         return;
  223.     }
  224.     /* This loop first processes the current segment, and then
  225.      * repeats if it can process the resequencing queue.
  226.      */
  227.     for(;;){
  228.         /* We reach this point with an acceptable segment; all data and flags
  229.          * are in the window, and the starting sequence number equals rcv.nxt
  230.          * (p. 70)
  231.          */    
  232.         if(seg.flags.rst){
  233.             if(tcb->state == SYN_RECEIVED
  234.              && !tcb->flags.clone && !tcb->flags.active){
  235.                 /* Go back to listen state only if this was
  236.                  * not a cloned or active server TCB
  237.                  */
  238.                 setstate(tcb,LISTEN);
  239.             } else {
  240.                 close_self(tcb,RESET);
  241.             }
  242.             free_p(bp);
  243.             return;
  244.         }
  245.         /* (Security check skipped here) p. 71 */
  246.         /* Check for precedence mismatch or erroneous extra SYN */
  247.         if(PREC(ip->tos) != PREC(tcb->tos) || seg.flags.syn){
  248.             free_p(bp);
  249.             reset(ip,&seg);
  250.             return;
  251.         }
  252.         /* Check ack field p. 72 */
  253.         if(!seg.flags.ack){
  254.             free_p(bp);    /* All segments after synchronization must have ACK */
  255.             return;
  256.         }
  257.         /* Process ACK */
  258.         switch(tcb->state){
  259.         case SYN_RECEIVED:
  260.             if(seq_within(seg.ack,tcb->snd.una+1,tcb->snd.nxt)){
  261.                 update(tcb,&seg);
  262.                 setstate(tcb,ESTABLISHED);
  263.             } else {
  264.                 free_p(bp);
  265.                 reset(ip,&seg);
  266.                 return;
  267.             }
  268.             break;
  269.         case ESTABLISHED:
  270.         case CLOSE_WAIT:
  271.             update(tcb,&seg);
  272.             break;
  273.         case FINWAIT1:    /* p. 73 */
  274.             update(tcb,&seg);
  275.             if(tcb->sndcnt == 0){
  276.                 /* Our FIN is acknowledged */
  277.                 setstate(tcb,FINWAIT2);
  278.             }
  279.             break;
  280.         case FINWAIT2:
  281.             update(tcb,&seg);
  282.             break;
  283.         case CLOSING:
  284.             update(tcb,&seg);
  285.             if(tcb->sndcnt == 0){
  286.                 /* Our FIN is acknowledged */
  287.                 setstate(tcb,TIME_WAIT);
  288.                 tcb->timer.start = MSL2 * (1000 / MSPTICK);
  289.                 start_timer(&tcb->timer);
  290.             }
  291.             break;
  292.         case LAST_ACK:
  293.             update(tcb,&seg);
  294.             if(tcb->sndcnt == 0){
  295.                 /* Our FIN is acknowledged, close connection */
  296.                 close_self(tcb,NORMAL);
  297.                 return;
  298.             }            
  299.             break;
  300.         case TIME_WAIT:
  301.             start_timer(&tcb->timer);
  302.             break;
  303.         }
  304.  
  305.         /* (URGent bit processing skipped here) */
  306.  
  307.         /* Process the segment text, if any, beginning at rcv.nxt (p. 74) */
  308.         if(length != 0){
  309.             switch(tcb->state){
  310.             case SYN_RECEIVED:
  311.             case ESTABLISHED:
  312.             case FINWAIT1:
  313.             case FINWAIT2:
  314.                 /* Place on receive queue */
  315.                 append(&tcb->rcvq,bp);
  316.                 tcb->rcvcnt += length;
  317.                 tcb->rcv.nxt += length;
  318.                 tcb->rcv.wnd -= length;
  319.                 tcb->flags.force = 1;
  320.                 /* Notify user */
  321.                 if(tcb->r_upcall)
  322.                     (*tcb->r_upcall)(tcb,tcb->rcvcnt);
  323.                 break;
  324.             default:
  325.                 /* Ignore segment text */
  326.                 free_p(bp);
  327.                 break;
  328.             }
  329.         }
  330.         /* process FIN bit (p 75) */
  331.         if(seg.flags.fin){
  332.             tcb->flags.force = 1;    /* Always respond with an ACK */
  333.  
  334.             switch(tcb->state){
  335.             case SYN_RECEIVED:
  336.             case ESTABLISHED:
  337.                 tcb->rcv.nxt++;
  338.                 setstate(tcb,CLOSE_WAIT);
  339.                 break;
  340.             case FINWAIT1:
  341.                 tcb->rcv.nxt++;
  342.                 if(tcb->sndcnt == 0){
  343.                     /* Our FIN has been acked; bypass CLOSING state */
  344.                     setstate(tcb,TIME_WAIT);
  345.                     tcb->timer.start = MSL2 * (1000/MSPTICK);
  346.                     start_timer(&tcb->timer);
  347.                 } else {
  348.                     setstate(tcb,CLOSING);
  349.                 }
  350.                 break;
  351.             case FINWAIT2:
  352.                 tcb->rcv.nxt++;
  353.                 setstate(tcb,TIME_WAIT);
  354.                 tcb->timer.start = MSL2 * (1000/MSPTICK);
  355.                 start_timer(&tcb->timer);
  356.                 break;
  357.             case CLOSE_WAIT:
  358.             case CLOSING:
  359.             case LAST_ACK:
  360.                 break;        /* Ignore */
  361.             case TIME_WAIT:    /* p 76 */
  362.                 start_timer(&tcb->timer);
  363.                 break;
  364.             }
  365.             /* Call the client again so he can see EOF */
  366.             if(tcb->r_upcall)
  367.                 (*tcb->r_upcall)(tcb,tcb->rcvcnt);
  368.         }
  369.         /* Scan the resequencing queue, looking for a segment we can handle,
  370.          * and freeing all those that are now obsolete.
  371.          */
  372.         while(tcb->reseq != NULLRESEQ && seq_ge(tcb->rcv.nxt,tcb->reseq->seg.seq)){
  373.             get_reseq(tcb,&ip->tos,&seg,&bp,&length);
  374.             if(trim(tcb,&seg,&bp,&length) == 0)
  375.                 goto gotone;
  376.             /* Segment is an old one; trim has freed it */
  377.         }
  378.         break;
  379. gotone:    ;
  380.     }
  381.     tcp_output(tcb);    /* Send any necessary ack */
  382. }
  383.  
  384. /* Process an incoming ICMP response */
  385. void
  386. tcp_icmp(source,dest,type,code,bpp)
  387. int32 source;            /* Original IP datagram source (i.e. us) */
  388. int32 dest;            /* Original IP datagram dest (i.e., them) */
  389. char type,code;            /* ICMP error codes */
  390. struct mbuf **bpp;        /* First 8 bytes of TCP header */
  391. {
  392.     struct tcp seg;
  393.     struct connection conn;
  394.     register struct tcb *tcb;
  395.  
  396.     /* Extract the socket info from the returned TCP header fragment
  397.      * Note that since this is a datagram we sent, the source fields
  398.      * refer to the local side.
  399.      */
  400.     ntohtcp(&seg,bpp);
  401.     conn.local.port = seg.source;
  402.     conn.remote.port = seg.dest;
  403.     conn.local.address = source;
  404.     conn.remote.address = dest;
  405.     if((tcb = lookup_tcb(&conn)) == NULLTCB)
  406.         return;    /* Unknown connection, ignore */
  407.  
  408.     /* Verify that the sequence number in the returned segment corresponds
  409.      * to something currently unacknowledged. If not, it can safely
  410.      * be ignored.
  411.      */
  412.     if(!seq_within(seg.seq,tcb->snd.una,tcb->snd.nxt))
  413.         return;
  414.  
  415.     /* Destination Unreachable and Time Exceeded messages never kill a
  416.      * connection; the info is merely saved for future reference.
  417.      */
  418.     switch(uchar(type)){
  419.     case DEST_UNREACH:
  420.     case TIME_EXCEED:
  421.         tcb->type = type;
  422.         tcb->code = code;
  423.         break;
  424.     case QUENCH:
  425.         /* Source quench; cut the congestion window in half,
  426.          * but don't let it go below one packet
  427.          */
  428.         tcb->cwind /= 2;
  429.         tcb->cwind = max(tcb->mss,tcb->cwind);
  430.         break;
  431.     }
  432. }
  433. /* Send an acceptable reset (RST) response for this segment
  434.  * The RST reply is composed in place on the input segment
  435.  */
  436. void
  437. reset(ip,seg)
  438. struct ip *ip;            /* Offending IP header */
  439. register struct tcp *seg;    /* Offending TCP header */
  440. {
  441.     struct mbuf *hbp;
  442.     struct pseudo_header ph;
  443.     int16 tmp;
  444.  
  445.     if(seg->flags.rst)
  446.         return;    /* Never send an RST in response to an RST */
  447.  
  448.     Tcp_stat.resets++;
  449.  
  450.     /* Compose the RST IP pseudo-header, swapping addresses */
  451.     ph.source = ip->dest;
  452.     ph.dest = ip->source;
  453.     ph.protocol = TCP_PTCL;
  454.     ph.length = TCPLEN;
  455.  
  456.     /* Swap port numbers */
  457.     tmp = seg->source;
  458.     seg->source = seg->dest;
  459.     seg->dest = tmp;
  460.  
  461.     if(seg->flags.ack){
  462.         /* This reset is being sent to clear a half-open connection.
  463.          * Set the sequence number of the RST to the incoming ACK
  464.          * so it will be acceptable.
  465.          */
  466.         seg->flags.ack = 0;
  467.         seg->seq = seg->ack;
  468.         seg->ack = 0;
  469.     } else {
  470.         /* We're rejecting a connect request (SYN) from LISTEN state
  471.          * so we have to "acknowledge" their SYN.
  472.          */
  473.         seg->flags.ack = 1;
  474.         seg->ack = seg->seq;
  475.         seg->seq = 0;
  476.         if(seg->flags.syn)
  477.             seg->ack++;
  478.     }
  479.     /* Set remaining parts of packet */
  480.     seg->flags.urg = 0;
  481.     seg->flags.psh = 0;
  482.     seg->flags.rst = 1;
  483.     seg->flags.syn = 0;
  484.     seg->flags.fin = 0;
  485.     seg->wnd = 0;
  486.     seg->up = 0;
  487.     seg->mss = 0;
  488.     if((hbp = htontcp(seg,NULLBUF,&ph)) == NULLBUF)
  489.         return;
  490.     /* Ship it out (note swap of addresses) */
  491.     ip_send(ip->dest,ip->source,TCP_PTCL,ip->tos,0,hbp,ph.length,0,0);
  492. }
  493.  
  494. /* Process an incoming acknowledgement and window indication.
  495.  * From page 72.
  496.  */
  497. static void
  498. update(tcb,seg)
  499. register struct tcb *tcb;
  500. register struct tcp *seg;
  501. {
  502.     int16 acked;
  503.     int16 expand;
  504.  
  505.     acked = 0;
  506.     if(seq_gt(seg->ack,tcb->snd.nxt)){
  507.         tcb->flags.force = 1;    /* Acks something not yet sent */
  508.         return;
  509.     }
  510.     /* Decide if we need to do a window update.
  511.      * This is always checked whenever a legal ACK is received,
  512.      * even if it doesn't actually acknowledge anything,
  513.      * because it might be a spontaneous window reopening.
  514.      */
  515.     if(seq_gt(seg->seq,tcb->snd.wl1) || ((seg->seq == tcb->snd.wl1) 
  516.      && seq_ge(seg->ack,tcb->snd.wl2))){
  517.         /* If the window had been closed, crank back the
  518.          * send pointer so we'll immediately resume transmission.
  519.          * Otherwise we'd have to wait until the next probe.
  520.          */
  521.         if(tcb->snd.wnd == 0 && seg->wnd != 0)
  522.             tcb->snd.ptr = tcb->snd.una;
  523.         tcb->snd.wnd = seg->wnd;
  524.         tcb->snd.wl1 = seg->seq;
  525.         tcb->snd.wl2 = seg->ack;
  526.     }
  527.     /* See if anything new is being acknowledged */
  528.     if(!seq_gt(seg->ack,tcb->snd.una))
  529.         return;    /* Nothing more to do */
  530.  
  531.     /* We're here, so the ACK must have actually acked something */
  532.     acked = seg->ack - tcb->snd.una;
  533.  
  534.     /* Expand congestion window if not already at limit */
  535.     if(tcb->cwind < tcb->snd.wnd){
  536.         if(tcb->cwind < tcb->ssthresh){
  537.             /* Still doing slow start/CUTE, expand by amount acked */
  538.             expand = min(acked,tcb->mss);
  539.         } else {
  540.             /* Steady-state test of extra path capacity */
  541.             expand = ((long)tcb->mss * tcb->mss) / tcb->cwind;
  542.         }
  543.         /* Guard against arithmetic overflow */
  544.         if(tcb->cwind + expand < tcb->cwind)
  545.             expand = MAXINT16 - tcb->cwind;
  546.  
  547.         /* Don't expand beyond the offered window */
  548.         if(tcb->cwind + expand > tcb->snd.wnd)
  549.             expand = tcb->snd.wnd - tcb->cwind;
  550.  
  551.         if(expand != 0){
  552. #ifdef    notdef
  553.             /* Kick up the mean deviation estimate to prevent
  554.              * unnecessary retransmission should we already be
  555.              * bandwidth limited
  556.              */
  557.             tcb->mdev += ((long)tcb->srtt * expand) / tcb->cwind;
  558. #endif
  559.             tcb->cwind += expand;
  560.         }
  561.     }
  562.     /* Round trip time estimation */
  563.     if(tcb->flags.rtt_run && seq_ge(seg->ack,tcb->rttseq)){
  564.         /* A timed sequence number has been acked */
  565.         tcb->flags.rtt_run = 0;
  566.         if(!(tcb->flags.retran)){
  567.             int32 rtt;    /* measured round trip time */
  568.             int32 abserr;    /* abs(rtt - srtt) */
  569.  
  570.             /* This packet was sent only once and now
  571.              * it's been acked, so process the round trip time
  572.              */
  573.             rtt = (Clock - tcb->rtt_time) * MSPTICK;
  574.  
  575.             /* If this ACKs our SYN, this is the first ACK
  576.              * we've received; base our entire SRTT estimate
  577.              * on it. Otherwise average it in with the prior
  578.              * history, also computing mean deviation.
  579.              */
  580.             if(rtt > tcb->srtt &&
  581.              (tcb->state == SYN_SENT || tcb->state == SYN_RECEIVED)){
  582.                 tcb->srtt = rtt;
  583.             } else {
  584.                 abserr = (rtt > tcb->srtt) ? rtt - tcb->srtt : tcb->srtt - rtt;
  585.                 /* Run SRTT and MDEV integrators, with rounding */
  586.                 tcb->srtt = ((AGAIN-1)*tcb->srtt + rtt + (AGAIN/2)) >> LAGAIN;
  587.                 tcb->mdev = ((DGAIN-1)*tcb->mdev + abserr + (DGAIN/2)) >> LDGAIN;
  588.             }
  589.             rtt_add(tcb->conn.remote.address,rtt);
  590.             /* Reset the backoff level */
  591.             tcb->backoff = 0;
  592.         }
  593.     }
  594.     /* If we're waiting for an ack of our SYN, note it and adjust count */
  595.     if(!(tcb->flags.synack)){
  596.         tcb->flags.synack = 1;
  597.         acked--;
  598.         tcb->sndcnt--;
  599.     }
  600.     /* Remove acknowledged bytes from the send queue and update the
  601.      * unacknowledged pointer. If a FIN is being acked,
  602.      * pullup won't be able to remove it from the queue.
  603.      */
  604.     pullup(&tcb->sndq,NULLCHAR,acked);
  605.  
  606.     /* This will include the FIN if there is one */
  607.     tcb->sndcnt -= acked;
  608.     tcb->snd.una = seg->ack;
  609.  
  610.     /* Stop retransmission timer, but restart it if there is still
  611.      * unacknowledged data.
  612.      */    
  613.     stop_timer(&tcb->timer);
  614.     if(tcb->snd.una != tcb->snd.nxt)
  615.         start_timer(&tcb->timer);
  616.  
  617.     /* If retransmissions have been occurring, make sure the
  618.      * send pointer doesn't repeat ancient history
  619.      */
  620.     if(seq_lt(tcb->snd.ptr,tcb->snd.una))
  621.         tcb->snd.ptr = tcb->snd.una;
  622.  
  623.     /* Clear the retransmission flag since the oldest
  624.      * unacknowledged segment (the only one that is ever retransmitted)
  625.      * has now been acked.
  626.      */
  627.     tcb->flags.retran = 0;
  628.  
  629.     /* If outgoing data was acked, notify the user so he can send more
  630.      * unless we've already sent a FIN.
  631.      */
  632.     if(acked != 0){
  633.         switch(tcb->state){
  634.          case ESTABLISHED:
  635.         case CLOSE_WAIT:
  636.             if(tcb->t_upcall){
  637.                 (*tcb->t_upcall)(tcb,tcb->window - tcb->sndcnt);
  638.             }
  639.         }
  640.     }
  641. }
  642.  
  643. /* Determine if the given sequence number is in our receiver window.
  644.  * NB: must not be used when window is closed!
  645.  */
  646. static
  647. int
  648. in_window(tcb,seq)
  649. struct tcb *tcb;
  650. int32 seq;
  651. {
  652.     return seq_within(seq,tcb->rcv.nxt,(int32)(tcb->rcv.nxt+tcb->rcv.wnd-1));
  653. }
  654.  
  655. /* Process an incoming SYN */
  656. static void
  657. proc_syn(tcb,tos,seg)
  658. register struct tcb *tcb;
  659. char tos;
  660. struct tcp *seg;
  661. {
  662.     int16 mtu;
  663.     struct tcp_rtt *tp;
  664.  
  665.     tcb->flags.force = 1;    /* Always send a response */
  666.  
  667.     /* Note: It's not specified in RFC 793, but SND.WL1 and
  668.      * SND.WND are initialized here since it's possible for the
  669.      * window update routine in update() to fail depending on the
  670.      * IRS if they are left unitialized.
  671.      */
  672.     /* Check incoming precedence and increase if higher */
  673.     if(PREC(tos) > PREC(tcb->tos))
  674.         tcb->tos = tos;
  675.     tcb->rcv.nxt = seg->seq + 1;    /* p 68 */
  676.     tcb->snd.wl1 = tcb->irs = seg->seq;
  677.     tcb->snd.wnd = seg->wnd;
  678.     if(seg->mss != 0)
  679.         tcb->mss = seg->mss;
  680.     /* Check the MTU of the interface we'll use to reach this guy
  681.      * and lower the MSS so that unnecessary fragmentation won't occur
  682.      */
  683.     if((mtu = ip_mtu(tcb->conn.remote.address)) != 0){
  684.         /* Allow space for the TCP and IP headers */
  685.         mtu -= TCPLEN + IPLEN;
  686.         tcb->cwind = tcb->mss = min(mtu,tcb->mss);
  687.     }
  688.     /* See if there's round-trip time experience */
  689.     if((tp = rtt_get(tcb->conn.remote.address)) != NULLRTT){
  690.         tcb->srtt = tp->srtt;
  691.         tcb->mdev = tp->mdev;
  692.     }
  693. }
  694.  
  695. /* Generate an initial sequence number and put a SYN on the send queue */
  696. void
  697. send_syn(tcb)
  698. register struct tcb *tcb;
  699. {
  700.     tcb->iss = geniss();
  701.     tcb->rttseq = tcb->snd.wl2 = tcb->snd.una = tcb->iss;
  702.     tcb->snd.ptr = tcb->snd.nxt = tcb->rttseq;
  703.     tcb->sndcnt++;
  704.     tcb->flags.force = 1;
  705. }
  706.  
  707. /* Add an entry to the resequencing queue in the proper place */
  708. static void
  709. add_reseq(tcb,tos,seg,bp,length)
  710. struct tcb *tcb;
  711. char tos;
  712. struct tcp *seg;
  713. struct mbuf *bp;
  714. int16 length;
  715. {
  716.     register struct reseq *rp,*rp1;
  717.  
  718.     /* Allocate reassembly descriptor */
  719.     if((rp = (struct reseq *)malloc(sizeof (struct reseq))) == NULLRESEQ){
  720.         /* No space, toss on floor */
  721.         free_p(bp);
  722.         return;
  723.     }
  724.     ASSIGN(rp->seg,*seg);
  725.     rp->tos = tos;
  726.     rp->bp = bp;
  727.     rp->length = length;
  728.  
  729.     /* Place on reassembly list sorting by starting seq number */
  730.     rp1 = tcb->reseq;
  731.     if(rp1 == NULLRESEQ || seq_lt(seg->seq,rp1->seg.seq)){
  732.         /* Either the list is empty, or we're less than all other
  733.          * entries; insert at beginning.
  734.          */
  735.         rp->next = rp1;
  736.         tcb->reseq = rp;
  737.     } else {
  738.         /* Find the last entry less than us */
  739.         for(;;){
  740.             if(rp1->next == NULLRESEQ || seq_lt(seg->seq,rp1->next->seg.seq)){
  741.                 /* We belong just after this one */
  742.                 rp->next = rp1->next;
  743.                 rp1->next = rp;
  744.                 break;
  745.             }
  746.             rp1 = rp1->next;
  747.         }
  748.     }
  749. }
  750.  
  751. /* Fetch the first entry off the resequencing queue */
  752. static void
  753. get_reseq(tcb,tos,seg,bp,length)
  754. register struct tcb *tcb;
  755. char *tos;
  756. struct tcp *seg;
  757. struct mbuf **bp;
  758. int16 *length;
  759. {
  760.     register struct reseq *rp;
  761.  
  762.     if((rp = tcb->reseq) == NULLRESEQ)
  763.         return;
  764.  
  765.     tcb->reseq = rp->next;
  766.  
  767.     *tos = rp->tos;
  768.     ASSIGN(*seg,rp->seg);
  769.     *bp = rp->bp;
  770.     *length = rp->length;
  771.     free((char *)rp);
  772. }
  773.  
  774. /* Trim segment to fit window. Return 0 if OK, -1 if segment is
  775.  * unacceptable.
  776.  */
  777. static int
  778. trim(tcb,seg,bpp,length)
  779. register struct tcb *tcb;
  780. register struct tcp *seg;
  781. struct mbuf **bpp;
  782. int16 *length;
  783. {
  784.     long dupcnt,excess;
  785.     int16 len;        /* Segment length including flags */
  786.     char accept = 0;
  787.  
  788.     len = *length;
  789.     if(seg->flags.syn)
  790.         len++;
  791.     if(seg->flags.fin)
  792.         len++;
  793.  
  794.     /* Acceptability tests */
  795.     if(tcb->rcv.wnd == 0){
  796.         /* Only in-order, zero-length segments are acceptable when
  797.          * our window is closed.
  798.          */
  799.         if(seg->seq == tcb->rcv.nxt && len == 0){
  800.             return 0;    /* Acceptable, no trimming needed */
  801.         }
  802.     } else {
  803.         /* Some part of the segment must be in the window */
  804.         if(in_window(tcb,seg->seq)){
  805.             accept++;    /* Beginning is */
  806.         } else if(len != 0){
  807.             if(in_window(tcb,(int32)(seg->seq+len-1)) || /* End is */
  808.              seq_within(tcb->rcv.nxt,seg->seq,(int32)(seg->seq+len-1))){ /* Straddles */
  809.                 accept++;
  810.             }
  811.         }
  812.     }
  813.     if(!accept){
  814.         tcb->rerecv += len;    /* Assume all of it was a duplicate */
  815.         free_p(*bpp);
  816.         return -1;
  817.     }
  818.     if((dupcnt = tcb->rcv.nxt - seg->seq) > 0){
  819.         tcb->rerecv += dupcnt;
  820.         /* Trim off SYN if present */
  821.         if(seg->flags.syn){
  822.             /* SYN is before first data byte */
  823.             seg->flags.syn = 0;
  824.             seg->seq++;
  825.             dupcnt--;
  826.         }
  827.         if(dupcnt > 0){
  828.             pullup(bpp,NULLCHAR,(int16)dupcnt);
  829.             seg->seq += dupcnt;
  830.             *length -= dupcnt;
  831.         }
  832.     }
  833.     if((excess = seg->seq + *length - (tcb->rcv.nxt + tcb->rcv.wnd)) > 0){
  834.         tcb->rerecv += excess;
  835.         /* Trim right edge */
  836.         *length -= excess;
  837.         trim_mbuf(bpp,*length);
  838.         seg->flags.fin = 0;    /* FIN follows last data byte */
  839.     }
  840.     return 0;
  841. }
  842.